//
//  ZoomingScrollView.m
//  MWPhotoBrowser
//
//  Created by Michael Waterfall on 14/10/2010.
//  Copyright 2010 d3i. All rights reserved.
//

#import "MWZoomingScrollView.h"
#import "MWPhotoBrowser.h"
#import "MWPhoto.h"
#import "UIImageView+WebCache.h"
#import "SDImageCache.h"
//#import "UIImage-Extensions.h"

// Declare private methods of browser
@interface MWPhotoBrowser ()
- (UIImage *)imageForPhoto:(id<MWPhoto>)photo;
- (NSURL *)previewImageUrlForPhoto:(id<MWPhoto>)photo;
- (void)cancelControlHiding;
- (void)cancelSlideShow;
- (void)hideControlsAfterDelay;
@end

// Private methods and properties
@interface MWZoomingScrollView ()
@property (nonatomic, assign) MWPhotoBrowser *photoBrowser;
- (void)handleSingleTap:(CGPoint)touchPoint;
- (void)handleDoubleTap:(CGPoint)touchPoint;
@end

@implementation MWZoomingScrollView

@synthesize photoBrowser = _photoBrowser, photo = _photo, captionView = _captionView, progressBar = _progressBar, loadBigImageButton = _loadBigImageButton;

#define ProgressBarFrame CGRectMake(20, 80, 28, 28)
#define LoadBigImageBtnFrame CGRectMake(50, 80, 60, 60)

- (id)initWithPhotoBrowser:(MWPhotoBrowser *)browser {
    if ((self = [super init])) {
        // Delegate
        self.photoBrowser = browser;
        
		// Tap view for background
		_tapView = [[MWTapDetectingView alloc] initWithFrame:self.bounds];
		_tapView.tapDelegate = self;
		_tapView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
		_tapView.backgroundColor = [UIColor blackColor];
		[self addSubview:_tapView];
		
		// Image view
		_photoImageView = [[MWTapDetectingImageView alloc] initWithFrame:CGRectZero];
		_photoImageView.tapDelegate = self;
		_photoImageView.contentMode = UIViewContentModeCenter;
		_photoImageView.backgroundColor = [UIColor blackColor];
		[self addSubview:_photoImageView];
        

        
        self.progressBar = [[[DACircularProgressView alloc] initWithFrame:ProgressBarFrame] autorelease];
//        progressView.tag = SDWEBIMAGE_UIVIEW_PROGRESS_TAG;
//        progressView.hidden = self.pbInfo.hidden;
        self.progressBar.autoresizingMask =   UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
        self.progressBar.tag = PROGRESS_BAR_TAG;
        self.progressBar.trackTintColor = [UIColor lightGrayColor];
        self.progressBar.progressTintColor = [UIColor whiteColor];
        [self addSubview:self.progressBar];
        self.progressBar.progress = 0.0;

        //loadBigImageButton
        self.loadBigImageButton = [UIButton buttonWithType:UIButtonTypeCustom];
//        self.loadBigImageButton.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleLeftMargin;
        self.loadBigImageButton.autoresizingMask = UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleRightMargin;
		self.loadBigImageButton.tag = LoadBigImageButton_BAR_TAG;
        self.loadBigImageButton.frame = LoadBigImageBtnFrame;
        [_loadBigImageButton setImage:[UIImage imageNamed:@"icon_gallery_magnify"] forState:UIControlStateNormal];
        [_loadBigImageButton addTarget:self action:@selector(loadingBigImageBtnPressed:) forControlEvents:UIControlEventTouchUpInside];
        
		// Setup
		self.backgroundColor = [UIColor blackColor];
		self.delegate = self;
		self.showsHorizontalScrollIndicator = NO;
		self.showsVerticalScrollIndicator = NO;
		self.decelerationRate = UIScrollViewDecelerationRateFast;
		self.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
    }
    return self;
}

- (IBAction)loadingBigImageBtnPressed:(UIButton*)sender{

    _progressBar.progress = 0;
    _progressBar.hidden = NO;
    _progressBar.frame = CGRectOffset(ProgressBarFrame, self.contentOffset.x, self.contentOffset.y);
//    MWPhoto * p = (MWPhoto*)self.photo;
//    if(p.isUnderlyingMiniImage) [_photo forceMinimodeLoadUnderlyingImageAndNotify];
    [_photo loadUnderlyingImageAndNotifyWithHDImage:YES];
    [sender removeFromSuperview];
}

- (void)loadOriginalImage
{
    _progressBar.progress = 0;
    _progressBar.hidden = NO;
    _progressBar.frame = CGRectOffset(ProgressBarFrame, self.contentOffset.x, self.contentOffset.y);
    [_photo loadUnderlyingImageAndNotifyWithHDImage:YES];
    [_photoBrowser setDisplayLoadOriginalPhotoButton:NO];
}

-(UIImageView*)photoIMGView
{
    return _photoImageView;
}

- (void)dealloc {

	[_tapView release];
	[_photoImageView release];
	
    if(self.photo) [(MWPhoto*)self.photo removeObserver:self forKeyPath:@"downloadProgress"];
//    [_spinner release];
    [_photo release];
    self.progressBar = nil;
	[super dealloc];
}

- (void)setPhoto:(id<MWPhoto>)newphoto {
    _photoImageView.image = nil; // Release image

    if (_photo) {
        [(MWPhoto*)_photo removeObserver:self forKeyPath:@"downloadProgress"];
        [_photo release];
        _photo = nil;
    }

    if (newphoto) {
        _photo =  [newphoto retain];
        [(MWPhoto*)_photo addObserver:self forKeyPath:@"downloadProgress" options:NSKeyValueObservingOptionNew context:nil];
    }


    
    self.scrollEnabled = YES;
    
    [self displayImage];

    _photoImageView.contentMode = UIViewContentModeScaleAspectFill;
     _photoImageView.clipsToBounds = YES;
    
}

- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
    if ([keyPath isEqualToString:@"downloadProgress"]) {
        if ([change objectForKey:NSKeyValueChangeNewKey] != [NSNull null])
        {
            double prog = [(NSNumber*)[change objectForKey:NSKeyValueChangeNewKey] doubleValue];
            //DebugLog(@"pic: %@, keyPath:%@, progress to show: %f",((MWPhoto*)self.photo).previewPhotoURL ,keyPath, prog);
            if([self.photo isEqual:object] && _progressBar && prog < 1.000000) [_progressBar setProgress: prog];
        }
    }
}

- (void)prepareForReuse {
    self.photo = nil;
    [_captionView removeFromSuperview];
    self.captionView = nil;
    [self.loadBigImageButton removeFromSuperview];
    
    [_gradMaskImgView removeFromSuperview];
    self.gradMaskImgView = nil;
    
    [_photoImageView setFrame:CGRectZero];
    
    self.maximumZoomScale = 1;
    self.minimumZoomScale = 1;
    self.zoomScale = 1;
    self.contentSize = self.bounds.size;
    self.contentOffset = CGPointZero;
}


#pragma mark - Image

// Get and display image
- (void)displayImage {
	if (_photo && _photoImageView.image == nil) {
		
        
		// Reset
		self.maximumZoomScale = 1;
		self.minimumZoomScale = 1;
		self.zoomScale = 1;
		self.contentSize = CGSizeMake(0, 0);

		// Get image from browser as it handles ordering of fetching
		UIImage *img = [self.photoBrowser imageForPhoto:_photo];
		if (img ) {
			
			// Hide spinner

            // Hide ProgressBar
            _progressBar.hidden = YES;
//            [_progressBar removeFromSuperview];
			
			// Set image
            MWPhoto * p = (MWPhoto*)_photo;
            int rotateDegree = 0;
            if (rotateDegree != 0) {
                img = [img imageRotatedByDegrees:rotateDegree];
            }

            CGRect photoImageViewFrame;
            photoImageViewFrame.origin = CGPointZero;
            photoImageViewFrame.size = CGSizeMake(floorf(img.size.width), floorf(img.size.height));
            _photoImageView.frame = photoImageViewFrame;
            self.contentSize = photoImageViewFrame.size;

            _photoImageView.image = img;
            _photoImageView.hidden = NO;

			// Set zoom to minimum zoom
			[self setMaxMinZoomScalesForCurrentBounds];
            
            // Setup photo frame
            

            
   
            
            if (![p currentPhotoIsHD] && p.previewPhotoURL) {
                [self.loadBigImageButton removeFromSuperview];
                CGRect suBounds = _photoImageView.bounds;
                self.loadBigImageButton.frame = CGRectMake(CGRectGetMaxX(suBounds) - 45, CGRectGetMaxY(suBounds) - 45, 60, 60);
                [_photoImageView addSubview:self.loadBigImageButton];
            }else{
                [self.loadBigImageButton removeFromSuperview];
            }
        }
        else {
            _progressBar.progress = 0;
			_progressBar.hidden = NO;
		}
		[self setNeedsLayout];
    } else {
        _progressBar.hidden = YES;
    }
}

-(void)chagePreviewImgToBig
{
    // previous image is nil
    if (_photoImageView.image == nil) {
        [self displayImage];
        return;
    }

    MWPhoto * p = (MWPhoto*)self.photo;

    UIImage *img = p.underlyingImage;
	if (_photo && p.underlyingImage) {
        
        CGFloat originScale = self.zoomScale;
        CGSize originImgSz = _photoImageView.image.size;
        CGPoint originOffset = self.contentOffset;

        CGFloat resultScale = (img.size.width > __FLT_EPSILON__) ? originScale * originImgSz.width / img.size.width : originScale;

		// Reset
		self.maximumZoomScale = 1;
		self.minimumZoomScale = 1;
		self.zoomScale = 1;
		self.contentSize = CGSizeMake(0, 0);

		if (img) {

            _progressBar.hidden = YES;

			// Set image
			_photoImageView.image = img;
			_photoImageView.hidden = NO;
            
            // Setup photo frame
            CGRect photoImageViewFrame;
            photoImageViewFrame.origin = CGPointZero;
            photoImageViewFrame.size = CGSizeMake(floorf(img.size.width), floorf(img.size.height));
            _photoImageView.frame = photoImageViewFrame;
            self.contentSize = photoImageViewFrame.size;
            
            [self.loadBigImageButton removeFromSuperview];
			// Set zoom to minimum zoom
			[self setMaxMinZoomScalesForCurrentBounds];
            
            
            self.zoomScale = resultScale;
            if (resultScale <= self.minimumZoomScale + __FLT_EPSILON__) {
                // Disable scrolling initially until the first pinch to fix issues with swiping on an initally zoomed in photo
                self.scrollEnabled = NO;
            } else {
                self.scrollEnabled = YES;
            }

            self.contentOffset = originOffset;
        }
		[self setNeedsLayout];
	}
}

// Image failed so just show black!
- (void)displayImageFailure {
//	[_spinner stopAnimating];
    _progressBar.hidden = YES;
    [self.loadBigImageButton removeFromSuperview];
}

#pragma mark - Setup

- (void)setMaxMinZoomScalesForCurrentBounds {
	
	// Reset
	self.maximumZoomScale = 1;
	self.minimumZoomScale = 1;
	self.zoomScale = 1;
	
	// Bail
	if (_photoImageView.image == nil) return;

	// Sizes
    CGSize boundsSize = self.bounds.size;
    CGSize imageSize = _photoImageView.image.size;
    
    // Calculate Min
    CGFloat xScale = boundsSize.width / imageSize.width;    // the scale needed to perfectly fit the image width-wise
    CGFloat yScale = boundsSize.height / imageSize.height;  // the scale needed to perfectly fit the image height-wise
    CGFloat minScale = MIN(xScale, yScale);                 // use minimum of these to allow the image to become fully visible
	
	// If image is smaller than the screen then ensure we show it at
	// min scale of 1
	if (xScale > 1 && yScale > 1) {
		minScale = 1.0;
        self.maximumZoomScale = 1.3;
        self.minimumZoomScale = 1;
        self.zoomScale = 1;
        [self setNeedsLayout];
        return;
	}

	// Calculate Max
	CGFloat maxScale = MAX(2.0f, [UIScreen mainScreen].scale); // Allow double scale
    // on high resolution screens we have double the pixel density, so we will be seeing every pixel if we limit the
    // maximum zoom scale to 0.5.
	if ([UIScreen instancesRespondToSelector:@selector(scale)]) {
		maxScale = maxScale / [[UIScreen mainScreen] scale];
	}

    //add by eric begin
    if(maxScale == 1.0 && minScale == 1.0) maxScale = 2.0;//zoom enable for the small image
    //add by eric end
    
	// Set
	self.maximumZoomScale = maxScale;
	self.minimumZoomScale = minScale;
    //add by eric begin
    self.zoomScale = minScale;
//    if (MIN(xScale, yScale) > 1.5) self.zoomScale = 1;
//    else if (MIN(xScale, yScale) > MAX(xScale, yScale) * 0.8){
//        self.zoomScale = MIN(xScale, yScale);
//        shouldDisplayFullImage = YES;
//    }
//    else self.zoomScale = MIN(xScale, yScale);
//    NSLog(@"self.zoomScale: %f", self.zoomScale);
    //add by eric end
	
	// Reset position
	_photoImageView.frame = CGRectMake(0, 0, _photoImageView.frame.size.width, _photoImageView.frame.size.height);
    
    if (shouldDisplayFullImage) {
        self.contentSize = self.frame.size;
    }
    MWPhoto * p = (MWPhoto*)self.photo;
    if (p.disableZooming) {
        self.maximumZoomScale = 1;
        self.minimumZoomScale = 1;
        self.zoomScale = 1;
    }
    
//    if ([p isUnderlyingMiniImage] == YES) {
//        self.maximumZoomScale = 1.3;
//        self.minimumZoomScale = 1;
//        self.zoomScale = 1;
//    }

    // If we're zooming to fill then centralise
    if (self.zoomScale <= minScale + __FLT_EPSILON__) {
        // Disable scrolling initially until the first pinch to fix issues with swiping on an initally zoomed in photo
        self.scrollEnabled = NO;
    }

	[self setNeedsLayout];
}

#pragma mark - Layout

- (CGSize)getImageViewSizeForVideoSize:(CGSize)videoSzie
{
    if (self.bounds.size.height > self.bounds.size.width) {
        CGFloat height = videoSzie.height * self.bounds.size.width / videoSzie.width;

        return CGSizeMake(ceilf(self.bounds.size.width), MIN(ceilf(height), self.bounds.size.height));
    } else {
        CGFloat width = videoSzie.width * self.bounds.size.height / videoSzie.height;

        return CGSizeMake(MIN(ceilf(width), self.bounds.size.width), ceilf(self.bounds.size.height));
    }
}

- (void)layoutSubviews {
	
	// Update tap view frame
	_tapView.frame = self.bounds;
	
	// Spinner
//	if (!_spinner.hidden) _spinner.center = CGPointMake(floorf(self.bounds.size.width/2.0),
//													  floorf(self.bounds.size.height/2.0));
    // Progress bar
    if(!_progressBar.hidden) _progressBar.frame = CGRectOffset(ProgressBarFrame, self.contentOffset.x, self.contentOffset.y);
    
	// Super
	[super layoutSubviews];
    

    // Center the image as it becomes smaller than the size of the screen
    CGSize boundsSize = self.bounds.size;
    CGRect frameToCenter = _photoImageView.frame;
    
    // Horizontally
    if (frameToCenter.size.width < boundsSize.width) {
        frameToCenter.origin.x = floorf((boundsSize.width - frameToCenter.size.width) / 2.0);
	} else {
        frameToCenter.origin.x = 0;
	}
    
    // Vertically
    if (frameToCenter.size.height < boundsSize.height) {
        frameToCenter.origin.y = floorf((boundsSize.height - frameToCenter.size.height) / 2.0);
	} else {
        frameToCenter.origin.y = 0;
	}
    
	// Center
    if (!CGRectEqualToRect(_photoImageView.frame, frameToCenter)) {
        _photoImageView.frame = frameToCenter;
    }
}

#pragma mark - UIScrollViewDelegate

- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
    return _photoImageView;
}

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView {
	[_photoBrowser cancelControlHiding];
    [_photoBrowser cancelSlideShow];
}

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {
    shouldDisplayFullImage = NO;
	[_photoBrowser cancelControlHiding];
    [_photoBrowser cancelSlideShow];
}

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale
{
    if (scale > scrollView.minimumZoomScale + __FLT_EPSILON__) {
        self.scrollEnabled = YES; // reset

        [_photoBrowser setDisplayLoadOriginalPhotoButton:YES];
    } else {
        self.scrollEnabled = NO; // reset

        [_photoBrowser setDisplayLoadOriginalPhotoButton:NO];
    }

    [[NSNotificationCenter defaultCenter] postNotificationName:@"BEGIN__ZOOMINGPHOTO__" object:_photoImageView];
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView
{
    [self setNeedsLayout];
    [self layoutIfNeeded];
}

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate {
	[_photoBrowser hideControlsAfterDelay];
}

#pragma mark - Tap Detection

- (void)singleTapActions
{
}
- (void)handleSingleTap:(CGPoint)touchPoint {
	[_photoBrowser performSelector:@selector(singleTapActions) withObject:nil afterDelay:0.2];
}

- (void)handleDoubleTap:(CGPoint)touchPoint {
    // 文字类型的不支持zoom 操作


	// Cancel any single tap handling
	[NSObject cancelPreviousPerformRequestsWithTarget:_photoBrowser];
	
	// Zoom
	if (self.zoomScale == self.maximumZoomScale) {
		
		// Zoom out
		[self setZoomScale:self.minimumZoomScale animated:YES];
        [_photoBrowser setDisplayLoadOriginalPhotoButton:NO];
	} else {
		
		// Zoom in
		[self zoomToRect:CGRectMake(touchPoint.x, touchPoint.y, 1, 1) animated:YES];
        [_photoBrowser setDisplayLoadOriginalPhotoButton:YES];
	}
	
	// Delay controls
	[_photoBrowser hideControlsAfterDelay];
}

// Image View
- (void)imageView:(UIImageView *)imageView singleTapDetected:(UITouch *)touch { 
    [self handleSingleTap:[touch locationInView:imageView]];
}
- (void)imageView:(UIImageView *)imageView doubleTapDetected:(UITouch *)touch {
    [self handleDoubleTap:[touch locationInView:imageView]];
}

// Background View
- (void)view:(UIView *)view singleTapDetected:(UITouch *)touch {
    [self handleSingleTap:[touch locationInView:view]];
}
- (void)view:(UIView *)view doubleTapDetected:(UITouch *)touch {
    [self handleDoubleTap:[touch locationInView:view]];
}






@end
